function ChartsControl(chart) {

    //传入数据
    this.data = {};
    this.myChart = chart;
    //表格原始数据
    this.spawn = {};
    this.rowHead = {};
    this.rowItems = {};
    //头部数据
    this.xHead = {};
    this.yHead = {};
    this.zHead = {};
    //表格数据
    this.tableData = [];
    //行列
    this.rows = 0;
    this.cols = 0;
    //配置参数
    this.flip = false;
    this.type = "bar";
    this.stack = [];
    this.fixed = [];
    this.changeXY = false;
    this.title = "";
    this.xIndex = 0;
    this.yIndex = 0;
    this.zIndex = 0;
    this.step = 1;
    this.unit = [];
    this.showInBar = false;
    this.axisPointer = "shadow";
    this.type = "bar";
    this.isFixed = false;
    this.rank = false;
    this.percent = false;
    this.reverse = false;
    this.showArea = false;


    this.xlen = 0 ;
    this.ylen = 0 ;
    this.zlen = 0 ;


    //返回参数
    this.option = {};

    //有关chart 描述
    this.chart = {
        x: [],
        y: [],
        z: [ [

        ] ]
    };

    //是否没有x表头
    this.hasX = true;
    this.hasY = true;

    Array.prototype.contains = function(ele) {

        if (JSON.stringify(this).indexOf(JSON.stringify( ele ))>= 0 ) {  return true;  }
        return false;
    };
    Array.prototype.pushUnique = function(newD) {
        if (this.contains(newD)) {
            return;
        }
        this.push(newD);
    };
    Array.prototype.toArray = function(name) {

        if(this.length == 0 ) return [{}];
        var res = [];

        for (var i = 0; i < this.length; i++) {

            res.push(this[i][name]);

        }
        return res;
    };
    //去重
    Array.prototype.unDuplicate = function(){

        var temp ;
        var size = 0 ;
        var res = [];
        var obj = {};

        for (var i = 0; i < this.length; i++) {

            if(!temp)temp = this[i];

            if(temp == this[i]){

                size += 1;
            }else{

                obj.step = size;
                obj.name = temp;

                res.push( obj );

//                obj = new Object();
                obj = {};

                temp = this [i];
                size = 1;
            }

            if(i==this.length-1){

                obj.step = size;
                obj.name = temp;
                res.push( obj );

            }

        }

        return res ;

    }

}
ChartsControl.prototype = {
    refresh:function( type ){
        this.init( type );
    },

    init: function(type, json, callbackObj) {

        this.error = ( callbackObj && callbackObj.error ) || function() {};

        if(this.myChart)this.myChart.clear();

        this.initOption();

        if (json) {

            this.data = json ;

        } else {

            this.error.call(this, "请全传入对应格式JSON数据") ;
        }

        if (!this.myChart) this.error.call(this, "请全传入要渲染的chart") ;

        if (type) this.type = type;

        try {
            //初始化chart
            this.chart = {};

            this.chart.x = this.data.c.x;

            this.chart.y = this.data.c.y;

            var z  = this.chart.z = this.data.c.v;

            for( var i = 0 ; i < z.length ; i ++ ){

                this.fixed.push( z[i][3]?z[i][3]:0 );

            }

            this.xlen = this.data.c.xN ;

            this.ylen = this.data.c.yN;

            this.zlen = this.data.c.vN;

            this.checkX();
            this.checkY();

//            if(this.data["d"]["r"]["f"][0] === "rank" ){
//                this.yIndex = 1;
//            }

        } catch (e) {

            this.error.call(this, "解析data出错");
        }
        try {

            this.splitData();

            this.initHead();

        } catch (e) {

            this.error.call(this, "初始化数据出错");

        }

        try {

            this.myChart.setOption( this.createChartOption( type ) );

        } catch (e) {

            this.error.call(this, "生成图表过程中出错了。");

        }


    },

    initOption: function() {

        this.flip = false;
        this.stack = [];
        this.fixed = [];
        this.changeXY = false;
        this.title = "";
        this.xIndex = 0;
        this.yIndex = 0;
        this.zIndex = 0;
        this.step = 1;
        this.unit = [];
        this.showInBar = false;
        this.axisPointer = "shadow";
        this.type = "bar";
        this.isFixed = false;
        this.rank = false;
        this.percent = false;
        this.reverse = false;
        this.showArea = false;

        this.xlen = 0 ;
        this.ylen = 0 ;
        this.zlen = 0 ;

    },
    /**
     * 分割数据
     */
    splitData: function() {

        this.spawn = this.data["d"]["h"]["r"];

        this.rowHead = this.data["d"]["h"]["i"];

        this.rowItems = this.data["d"]["r"]["i"];

//        console.log( this.rowHead ,this.chart.x ,this.chart.y ,this.chart.z);

        var head = [];

        for(var i = 0 ; i < this.chart.x.length ; i++){

            for(var j =0 ; j< this.rowHead[0].length ; j++){

                if(this.rowHead[0][j]["t"].indexOf(this.chart.x[i])==0){

                    head.push(this.rowHead[0][j]);
                }
            }

        }
        for(var i = 0 ; i < this.chart.y.length ; i++){

            for(var j =0 ; j< this.rowHead[0].length ; j++){

                if(this.rowHead[0][j]["t"].indexOf(this.chart.y[i])==0){

                    head.push(this.rowHead[0][j]);
                }
            }

        }
        for(var i = 0 ; i < this.chart.z.length ; i++){

            for(var j =0 ; j< this.rowHead[0].length ; j++){

                if(this.rowHead[0][j]["t"].indexOf(this.chart.z[i][0])==0){

                    head.push(this.rowHead[0][j]);
                }
            }

        }
//        this.rowHead[0] = head;

    },
    /**
     * 初始化表头
     */
    initHead: function() {
        //HY
        var yName = [];
        //C1 C2...
        var dataName = [];

        var ysize = this.data["d"]["h"]["f"].length;

        for (var i = 0; i < this.rowHead.length; i++) {

            var dat = this.rowHead[i];
            //xHead
            this.xHead[i] = [];

            for (var j = 0; j < dat.length; j++) {

                var obj = {};



                if(dat[j]["f"] == "total"||dat[j]["f"]=="rank") continue;

                if( j < ysize ) {
                    yName.pushUnique(dat[j]["f"]);
                }
                else
                {
                    //t 名字
                    obj.name = dat[j]["t"];
                    //c 步长
                    obj.step = dat[j]["c"] ? dat[j]["c"] : 1;

                    this.xHead[i].pushUnique( obj );
                    //最后一个数组

                    if (i == this.rowHead.length - 1) {

                        dataName.pushUnique(dat[j]["f"]);
                    }
                }

            }

        }


        //yHead
        for (var j = 0; j < yName.length; j++) {

            var obj = { };

            obj.step = 0 ;

            var tempArray = [] ;

            for (var i = 0; i < this.rowItems.length; i++) {
                //增加yHead

                var dat = this.rowItems[i];

                var name = dat[ yName[ j ] ];

                tempArray.push( name );

            }

            if(tempArray.length!=0){

                this.yHead[j] = tempArray.unDuplicate();
            }

        }

        //tableData
        for (var i = 0; i < this.rowItems.length; i++) {

            var dat = this.rowItems[i];

            this.tableData[i] = [];

            //tableData获取
            for (var k = 0; k < dataName.length; k++) {

                if (dataName[k]) this.tableData[i].push(dat[dataName[k]]);

            }

        }


//        console.log( "y"+JSON.stringify( this.yHead) );
//        console.log( "x"+JSON.stringify( this.xHead) );

        {
            this.rows = this.tableData.length;

            this.cols = dataName.length;

            var zc = this.chart.z;

            this.unit = [];

            for (var i = 0; i < zc.length; i++) {

                this.unit.push(zc[i]);

                this.zHead[i] = [];

                if (zc.length > 0) {

                    var tt = zc[i];

                    var obj = {};

                    obj.name = tt[0];

                    obj.cal = tt[1];

                    obj.unit = tt[2];

                    this.zHead[i].push(obj);
                }

            }
        }

    },
    /**
     * 获取指定数据
     * @param des
     * @returns {Array}
     */
    getData: function( des ) {

        var xm,ym;

        if(this.xHead[ this.xIndex ])
            xm  = this.xHead[ this.xIndex ].toArray("step");

        if(this.yHead[this.yIndex])
            ym = this.yHead[this.yIndex].toArray("step");

//        console.log( this.chart.z);

        var z_len = this.chart.z.length ;

//        console.log("xm",xm,"ym",ym , this.yHead ,this.chart.z);

        var res = [];

        var time = 0 ;

        for (var i = 0; i < this.rows; ) {

            var temp = 0,size = 0 ,obj = {} , array = [];

            var step = ym[time++];


            for(var k = 0 ; k < step ; k++){

                var rr = this.getRows( i+k , 0 , xm );


                for(var j =0 ; j < rr.length ; j++){

                    var tt =  parseFloat( rr[ j ]["total"]);

                    for (var kk = 0; kk < z_len; kk++) {

                        if (!obj[kk]) obj[kk] = [];

                        if (!obj[kk][j])obj[kk][j] = 0;

                        obj[kk][j] += parseFloat(rr [j][ kk ]);

                    }

                    temp += tt;

                    if( !array[j] ) array[j] = 0;

                    array[ j ] += tt;

                    size += parseInt( rr[j]["size"] );

                }

            }


            var avg = (temp/size).toFixed( 2 );

            obj.total = array;

            obj.avg = avg ;

            res.push( obj );

            i += step ;
        }


        if (des == "y") {

            res = this._change( res )
        }

        //数据倒序
        if( this.reverse ){
            var res2 = [];
            for(var i = res.length -1 ; i >= 0  ; i--){
                res2.push(res[i]);
            }
            return res2;
        }



        return res;
    },
    /**
     * 获取行数据
     * @param row , step
     * @returns {Array}
     * @param start
     * @param xm
     */
    getRows: function(row, start, xm) {

        var res = [];

        var time = 0 ;

        for (var i = start ; i < this.cols;) {

            var obj = {};

            var step = xm [ time ];

            if(!this.hasX){
                step = 1;
            }

            var temp = 0 ;

            var count = step ;

            for (var k = 0; k < step; k++) {

                var dd = this.tableData[ row ][ i+k ];

                var tt = parseFloat(dd)? parseFloat(dd) : 0;

                obj [ k ] = tt;

                temp += tt ;

                if(tt == 0){

                    count--;

                }

            }
            obj.total = temp.toFixed(2);

            obj.size = count;

            i += step;

            res.push( obj );

            time++;

        }

        return res;
    },
    /**
     * 获取列数据
     * @param col , step
     * @returns {*}
     * @param start
     * @param step
     */
    getCols: function(col, start, step) {

        var res = [];

        for (var i = start; i < this.rows; i += step) {

            res.push(this.tableData[i][col]);

        }
        return res;

    },

    checkX:function(){

        for(var jj = 0 ; jj< this.chart.z.length ; jj ++){

            for (var i = 0; i < this.chart.x.length; i++) {


                if (this.chart.z[jj][0] == this.chart.x[i][0]) {

                    this.hasX = false;

                    return false;

                }
            }

        }
        this.hasX = true;
        return true;

    },

    checkY:function(){

        for(var jj = 0 ; jj< this.chart.z.length ; jj ++){

            for (var i = 0; i < this.chart.y.length; i++) {

                if (this.chart.z[jj][0] == this.chart.y[i][0]||this.chart.y[i]=="统计方式") {

                    this.hasY = false;

                    return false;

                }
            }

        }
        this.hasY = true;
        return true;

    },

    /**
     * 返回各种构造好的option
     * @returns {*}
     */
    createChartOption: function(type, x, y, z, flip, change) {

        if (type) {

            this.type = type;
        }
        if (typeof(x) == "number") {

            this.xIndex = x;
        }
        if (typeof(y) == "number") {

            this.yIndex = y;
        }
        if (typeof(z) == "number") {

            this.zIndex = z;
        }
        this.flip = !!flip;

        this.changeXY = !!change;

        this.title = "";

        this.unit = [];

//        this.zIndex =2;



        if (type == "pie") {

            return this.createPieOption();

        } else if (type == "line") {

            return this.createLineOption();

        } else if (type == "fixed") {

            return this.createFixed();

        } else if (type == "xBar") {

            return this.createXBar();

        } else if (type == "yBar") {

            return this.createYBar();

        } else if(type =="pxBar"){

            return this.createPXBar();

        }else if(type =="pyBar"){

            return this.createPYBar();
        }else if(type =="sybar"){

            return this.createSYBar();
        }else if(type =="sline"){

            return this.createSLine();
        } else{

            return this.createBarOption();
        }

    },

    setOption: function(option) {

        for (var i in option) {

            if(this[i])this[i] = option[i];
        }
    },

    getOption: function() {

        return this.option;

    },

    _change: function ( data ) {

        var res = [];

        var obj = {};

        var z_len = this.chart.z.length;

        for(var i =0 ; i < data.length ; i++){

            for( var j = 0 ; j < data[i]["total"].length ; j++){

                if(!this.hasX){

                    z_len = 1;
                }


                for(var z = 0 ; z < z_len ; z++ ){

                    if( !obj[z] ) obj[z]= {};

                    if( !obj[z][ j ] ) obj[z][j]=[];

                    obj[z][ j ].push(  data[i][z][j] );

                }

                var tt = data[i]["total"][j];

                if( !obj["total"] ) obj["total"]= {};

                if( !obj["total"][ j ] ) obj["total"][j]=[];

                obj["total"][ j ].push( tt );

            }
        }

        for( var ob in obj["total"] ){

            var obj2 = {};

            obj2.total = obj["total"][ ob ];

            for(var z = 0 ; z < z_len ; z++ ) {

                obj2[z] =  obj[ z ][ ob ];

            }

            res.push( obj2 );

        }

        return res ;
    },

    createOption: function() {

        var d  = this.getData("x"),

            yh = this.yHead[this.yIndex].toArray("name"),

            xh = this.xHead[ this.xIndex ].toArray("name");


        if(!this.checkX()){

            this.flip = true;
        }
        this.checkY();


        //翻转
        if (this.flip) {

            d = this._change( d );

            xh = this.yHead[this.yIndex].toArray("name");

            yh = this.xHead[this.xIndex].toArray("name");

        }

        //条形图 修改
        var _index = [];


        if(!this.hasY){

            var temp = [];
            for(var i = 0 ; i < xh.length; i++){
                for(var j = 0 ; j < this.chart.z.length ; j++){

                    if(xh[i].indexOf(this.chart.z[j][0])==0){
                        temp.pushUnique(xh[i]);
                        _index.push( i );
                    }

                }
            }
            xh = temp;
        }


        if( !this.hasX ){
            var temp = [];

            for(var i = 0 ; i < yh.length; i++){

                for(var j = 0 ; j < this.chart.z.length ; j++){

                    if(yh[i].indexOf(this.chart.z[j][0])==0){

                        temp.pushUnique(yh[i]);

                        _index.push( i );
                    }

                }
            }
            yh = temp;

        }

        if(this.percent){

            d = this.changeToPercent( d );

        }

        this.option.title = {

            text: this.title
        };

        if (!this.flip && xh.length > 60) {

            this.option.Zoom = {
                show: true
//                start: 0,
//                end: 20
            };
        }

        this.option.tooltip = {

            trigger: "axis",

            axisPointer: {

                type: "shadow"
            }
        };

        if(this.percent){

            this.option.tooltip = {
                trigger: 'axis',
                formatter:function (params,ticket,callback) {

                    var res = '' + params[0][1];

                    for (var i = 0, l = params.length; i < l; i++) {

                        res += '<br/>' + params[i][0] + ' : ' +params[i][2].toFixed(2)+" % ";

                    }
                    return res;
                },
                axisPointer: {}
            };

        };

        if (this.axisPointer == "line") {

            this.option.tooltip.axisPointer.type = "line";
        }
        else if (this.axisPointer == "shadow") {

            this.option.tooltip.axisPointer.type = "shadow";
        }

        this.option.legend = {

            data: yh
        };

        this.option.calculable = false;
        //xAxis
        this.option.xAxis = {

            type: 'category',

            data: xh
        };

        if(this.showArea){
            this.option.xAxis. boundaryGap  = false;
        }
        //yAxis
        this.option.yAxis = [];

        for (var z = 0; z < this.fixed.length; z++) {

            var obj = {};

            obj.type = "value";

            if(this.percent){
                obj.axisLabel = {
                    formatter: '{value} %'
                };
                obj.max = 100;
            }

            obj.name = this.unit[z]?this.unit[z]:"";

            this.option.yAxis.push(obj);
        }

        //xy轴转换
        if ( this.changeXY ) {

            var temp = this.option.xAxis;

            this.option.xAxis = this.option.yAxis ;

            this.option.yAxis = temp;
        }

        //翻转头部
        if(this.reverse){
            var ytemp = [];
            var yy = this.option.yAxis["data"];
            for(var i = yy.length-1 ; i >= 0; i--){

                ytemp.push(yy[i]);
            }
            this.option.yAxis["data"] = ytemp;
        }

        //series
        this.option.series = [];

        var xNames = [];

        var len = this.fixed.length;


//        没有x或者没有y的情况

        if( len != 1&&(this.ylen ==0 ||this.xlen==0)){

            for(var i = 0 ; i < d.length ; i ++){

                for(var j = 0 ; j < len ; j ++ ){

                    var obj = {};

                    obj.name = yh[i];

                    if((!this.checkY()||!this.checkX())&&j!=0){
                        continue;
                    }

                    xNames.push( obj.name );

                    obj.type = this.type;
                    //量价图改变
                    if (this.fixed[ i ] == "r"&&this.isFixed) {

                        obj.type = "line";

                        obj.yAxisIndex = 1;
                    }else if(this.type == "line") {
                        obj.type = "line";

                    }else{
                        obj.type = "bar";
                    }

                    obj.data = d[i]["total"];


                    if (this.showInBar) {
                        obj.itemStyle = {
                            normal: {
                                label: {
                                    show: true,
                                    position: 'inside'
                                }
                            }
                        }
                    };
                    if (this.showArea) {
                        obj.itemStyle = {
                            normal: {areaStyle: {type: 'default'}}
                        }
                    };

                    this.option.series.pushUnique(obj);
                }
            }

            return this.option;
        }

        //生成series
        for(var kk = 0 ; kk <  len  ; kk++){


            for (var i = 0; i < yh.length ; i += 1) {

                var obj = {};

                if(!this.hasX && i != 0 ){

                    continue;

                }
                if( (!this.hasX||!this.hasY) && i == 0){

                    obj.name = yh[kk];

                }else{
                    obj.name = yh[i];
                }

                obj.name = yh[i];

                for(var xx = 0 ; xx< kk ; xx++){

                    obj.name+="_";
                }

                xNames.push( obj.name );

                obj.type = this.type;
                //量价图改变
                if (this.fixed[ kk ] == "r") {

                    obj.type = "line";

                    obj.yAxisIndex = 1;
                }
                //获取值的方式
//                if( this.fixed.length == 1 || !this.checkX() || !this.checkY()){
//
//                    obj.data = d[i]["total"];
//                }else{
//
//                    obj.data = d[i][kk];
//                }

                if(len ==1){
                    obj.data = d[i]["total"];
                }else{
                    obj.data = d[i][kk];
                }

                if(!this.hasX||!this.hasY){
                    obj.data = d[_index[i]]["total"];
                }

                //堆叠
                if (this.stack.length == 1) {

                    obj.stack = "0";

                } else {
                    obj.stack = this.stack[i];
                }

                if (this.showInBar) {
                    obj.itemStyle = {
                        normal: {
                            label: {
                                show: true,
                                position: 'inside'
                            }
                        }
                    };
                }

                if (this.showArea) {
                    obj.itemStyle = {
                        normal: {areaStyle: {type: 'default'}}
                    }
                };

                if(this.percent){
                    obj.itemStyle = {};
                }

                this.option.series.push(obj);
            }

        }

        if(this.fixed.length !=1 ){
            this.option.legend = {
                data: xNames
            };
        }

        return this.option;
    },


    containIndex:function(arr ,target ){
        for(var i = 0 ;i<arr.length;i++){
            if(arr[i]==target){
                return true;
            }
        }
        return false;
    },

    changeToPercent:function( data ){

        var res = data ;

        var total = [];

        for( var i =0 ; i < data.length ; i++){

            for( var j =0 ; j < data[i]["total"].length ; j++){

                if(!total[j])total[j] = 0;

                total[j]+=data[i]["total"][j];
            }

        }

        for( var i =0 ; i < data.length ; i++){

            for( var j =0 ; j < data[i]["total"].length ; j++){

                res[i]["total"][j] = ((100*data[i]["total"][j])/total[j]);

            }
        }
        return res;

    },


    createBarOption: function() {

        this.type = "bar";

        this.stack = [];

        return this.createOption();
    },

    createLineOption: function() {
        this.type = "line";

        this.stack = [];

        this.axisPointer = "line";


        this.createOption();

        return this.getOption();
    },

    createFixed: function() {

        this.type = "bar";

        this.isFixed = true;

        this.createOption();

        return this.getOption();
    },

    createPXBar:function(){

        this.percent = true;

        return this.createXBar();
    },
    /**
     * 创建比例柱状图 charts参数
     **/

    createXBar: function() {

        this.stack = [1];

        this.changeXY = false;

        this.type = "bar";

        this.showInBar = true;

        this.createOption();

        return this.getOption();

    },
    createPYBar:function(){

        this.percent = true;

        return this.createYBar();
    },
    /**
     * 创建比例条形 charts参数
     **/
    createYBar: function() {

        this.stack = [1];

        this.changeXY = true;

        this.showInBar = true;

        this.type = "bar";

        this.createOption();

        return this.getOption();

    },
    createSYBar:function(){
        this.type = "bar";

        this.stack = [];

        this.reverse = true;

        this.changeXY = true;

        return this.createOption();
    },
    createSLine:function(){
        this.type = "line";

        this.stack = [];

        this.axisPointer = "line";

        this.stack = [1];

        this.showArea = true;

        this.createOption();

        return this.getOption();
    },

    createPieOption: function() {
        var d  = this.getData( "x" ) ,
            yh = this.yHead[ this.yIndex ].toArray("name"),
            xh = this.xHead[ this.xIndex ].toArray("name"),
            zh = this.zHead[ this.zIndex ];
        //排名不显示rank值
        if(this.data["d"]["r"]["f"][0] =="rank"){
//            console.log( this.yHead );
//            yh = this.yHead[ this.yIndex+1 ].toArray("name");
        }

        var xData = [] ,
            yData = [] ;

        for( var i = 0 ; i < d.length ;i++){

            var temp = 0 ;

            var dTotal =  d[i]["total"];

            for(var j =0 ; j <dTotal.length ; j ++){
                // 0
                var fData = dTotal[ j ] ;

                temp += fData;

                if( !yData[j] ) yData[j] = 0 ;

                yData[j] += fData;

            }

            xData.push( temp );

        }

//        var title = this.chart.x[this.xIndex] + " - " + zh[0].name + zh[0].cal + " 饼图 ";
        var title = "";

        this.option = {

            title: {
                text: title,
                subtext: '',
                x: 'center'
            },
            tooltip: {
                trigger: 'item',
                formatter: "{a} <br/>{b} : {c} ({d}%)"
            }
        };

        this.option.series = [];


        var obj = {};

        obj.name = zh[0].name + zh[0].cal + "(" + zh[0].unit + ")";

        obj.type = this.type;

        obj.radius = "55%";

        obj.center = ['30%', '60%'];

        obj.data = [];

        for (var i = 0; i < xh.length ; i++) {

            var tm = {};

            tm.name = xh [ i ];

            tm.value = yData [ i ];

            obj.data.push( tm );

        }
        if( !this.checkY() ){

            obj.center = ['50%', '60%'];
        }

        if( this.checkX() ){

            this.option.series.push( obj) ;

        }


        obj = {};

        obj.name = zh[0].name + zh[0].cal + "(" + zh[0].unit + ")";

        obj.type = this.type;

        obj.radius = "55%";

        obj.center = ['70%', '60%'];

        obj.data = [];

        for (var i = 0; i < yh.length ; i++) {

            var tm = {};

            tm.name = yh [ i ];

            tm.value = xData [ i ];

            obj.data.push( tm );

        }

        if( !this.checkX() ){

            obj.center = ['50%', '60%'];
        }

        if( this.checkY() ) {

            this.option.series.push( obj );
        }

        return this.getOption();

    },
    /**
     * 打印数据
     */
    log: function() {

    }

};